#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>

template<class T>
using func_t = std::function<void(T&)>;

template<class T>
class thread{
public:
    thread(const std::string& threadname, func_t<T> func, const T& data)
    :_tid(0),_threadname(threadname),_func(func),_data(data),isrunning(false)
    {}
    static void *rountine(void* args)
    {
        thread* ts = static_cast<thread*>(args);
        ts->_func(ts->_data);
        return NULL;
    }  
    bool start()
    {
        int n = pthread_create(&_tid, NULL, rountine, this);
        if(n == 0)
        {
            isrunning = true;
            return true;
        }
        else return false;
    }
    bool join()
    {
        if(!isrunning)return true;
        int n = pthread_join(_tid, NULL);
        if(n == 0)
        {
            isrunning = false;
            return true;
        }
        else return false;
    }
    std::string name()
    {
        return _threadname;
    }
    bool is_running()
    {
        return isrunning;
    }
    ~thread(){}

private:
    T _data;
    pthread_t _tid;//thread_id
    std::string _threadname;
    func_t<T> _func;
    bool isrunning;

};